package main

import "fmt"

/*
在Go中，函数也是一种数据类型，可以赋值给一个变量，则该变量就是一个函数类型的变量了。通过该变量可以对函数调用
*/
func test2(num int) {
	fmt.Println(num)
}

//定义一个函数，把另一个函数作为形参：
//函数既然是一种数据类型，因此在Go中，函数可以作为形参，并且调用
//（把函数本身当做一种数据类型）
func test02(num1 int, num2 float32, testFunc func(int)) {
	testFunc(num1)
	fmt.Println("-----test02")
}

/*
为了简化数据类型定义,Go支持自定义数据类型
基本语法: type 自定义数据类型名  数据类型
可以理解为 : 相当于起了一个别名
例如:type mylnt int -----》这时mylnt就等价int来使用了.
*/
type myFunc func(int)

func test03(num1 int, num2 float32, testFunc myFunc) {
	testFunc(num1)
	fmt.Println("-----test03")
}

/*
传统写法要求：返回值和返回值的类型对应，顺序不能差
*/
func test04(num1 int, num2 int) (int, bool) {
	res1 := num1 + num2
	res2 := num1 == num2
	return res1, res2
}

/*
对函数返回值命名，里面顺序就无所谓了，顺序不用对应
*/
func test05(num1 int, num2 int) (res1 int, res2 bool) {
	res1 = num1 + num2
	res2 = num1 == num2
	return
}

func main() {
	//函数也是一种数据类型，可以赋值给一个变量
	a := test2                                        //变量就是一个函数类型的变量
	fmt.Printf("a的类型是：%T,test函数的类型是：%T \n", a, test2) //a的类型是：func(int),test函数的类型是：func(int)
	fmt.Println()

	//通过该变量可以对函数调用
	a(10) //等价于  test2(10)
	fmt.Println()

	//调用test02函数：
	test02(20, 3.19, test2)
	fmt.Println()

	test02(30, 3.19, a)
	fmt.Println()

	test03(40, 3.19, a)
	fmt.Println()

	test04(10, 3)
	fmt.Println()

	test05(10, 10)
	fmt.Println()
}
